package com.jiangyifen.robot.service.impl;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.jiangyifen.framework.db.dao.SuperDao;
import com.jiangyifen.framework.util.MacAddressUtil;
import com.jiangyifen.robot.core.Robot;
import com.jiangyifen.robot.core.RobotImpl;
import com.jiangyifen.robot.entity.RobotYunXiaoMiEntity;
import com.jiangyifen.robot.sdk.event.HumanSilenceEvent;
import com.jiangyifen.robot.service.RobotService;
import com.jiangyifen.robot.service.RobotSessionService;

@Service
public class RobotServiceImpl implements RobotService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private static Map<Long, Robot> robotMap = new ConcurrentHashMap<>();

	private static final int CUSTOMER_SILENCE = 5000;

	@Value("${localIp}")
	private String localIp = "";

	@Value("${ttsTempPathForWindows}")
	private String ttsTempPathForWindows = "";

	@Value("${ttsTempPathForLinux}")
	private String ttsTempPathForLinux = "";
	
	@Value("${wavFileHomeForLinux}")
	private String wavFileHomeForLinux = "";

	@Value("${wavFileHomeForWindows}")
	private String wavFileHomeForWindows = "";
	
	@Autowired
	private SuperDao superDao;

	@Autowired
	private RobotSessionService sessionService;

	@PostConstruct
	private void init() {
		// silenceDetectThread，用于检测人类长时间不说话
		new Thread(() -> {
			while (true) {
				try {
					Thread.sleep(1000);
					for (Robot robot : robotMap.values()) {
						long current = System.currentTimeMillis();
						long last = robot.getLastSilenceTimestamp();
						logger.debug("robotId={}, current={}, last={}, (current - last)={}", robot.getId(), current,
								last, current - last);
						if (last == 0) {
							continue;
						}
						if (current - last > CUSTOMER_SILENCE) {
							HumanSilenceEvent e = new HumanSilenceEvent();
							e.setRobotId(robot.getId());
							robot.onHumanSilence(e);
							robot.setLastSilenceTimestamp(0);
						}
					}
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
				}
			}
		}).start();

	}

	private void startup(RobotYunXiaoMiEntity robotEntity, Long scenarioId) throws IOException {
		String os = MacAddressUtil.getOSName();
		String ttsTempPath = null;
		String wavHome = null;
		if (os.startsWith("windows")) {
			ttsTempPath = ttsTempPathForWindows;
			wavHome = wavFileHomeForWindows;
		} else {
			ttsTempPath = ttsTempPathForLinux;
			wavHome = wavFileHomeForLinux;
		}
		Robot robot = new RobotImpl(sessionService, scenarioId, robotEntity, localIp, ttsTempPath, wavHome);
		robotMap.put(robot.getId(), robot);
	}

	@Override
	public void startup(Long robotId, Long scenarioId) throws IOException {
		RobotYunXiaoMiEntity robotEntity = superDao.get(robotId, RobotYunXiaoMiEntity.class);
		startup(robotEntity, scenarioId);
	}

	@Override
	public void startupAll(Long scenarioId) {
		List<RobotYunXiaoMiEntity> allRobotEntity = superDao.getAll(RobotYunXiaoMiEntity.class);
		for (RobotYunXiaoMiEntity robotEntity : allRobotEntity) {
			try {
				startup(robotEntity, scenarioId);
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	@Override
	public void shutdown(Long robotId) {
		Robot r = this.getRobot(robotId);
		r.getAliyunASRClient().shutdonw();
		r.getSipPhoneClient().unregister();
		robotMap.remove(robotId);
	}

	@Override
	public void shutdownAll() {
		for (Robot r : robotMap.values()) {
			shutdown(r.getId());
		}
	}

	@Override
	public Map<Long, Robot> getAllRobots() {
		return robotMap;
	}

	@Override
	public Robot getRobot(Long robotId) {
		return robotMap.get(robotId);
	}

	public String getLocalIp() {
		return localIp;
	}

	public void setLocalIp(String localIp) {
		this.localIp = localIp;
	}

	public String getTtsTempPathForWindows() {
		return ttsTempPathForWindows;
	}

	public void setTtsTempPathForWindows(String ttsTempPathForWindows) {
		this.ttsTempPathForWindows = ttsTempPathForWindows;
	}

	public String getTtsTempPathForLinux() {
		return ttsTempPathForLinux;
	}

	public void setTtsTempPathForLinux(String ttsTempPathForLinux) {
		this.ttsTempPathForLinux = ttsTempPathForLinux;
	}

	public String getWavFileHomeForLinux() {
		return wavFileHomeForLinux;
	}

	public void setWavFileHomeForLinux(String wavFileHomeForLinux) {
		this.wavFileHomeForLinux = wavFileHomeForLinux;
	}

	public String getWavFileHomeForWindows() {
		return wavFileHomeForWindows;
	}

	public void setWavFileHomeForWindows(String wavFileHomeForWindows) {
		this.wavFileHomeForWindows = wavFileHomeForWindows;
	}

}
